package main;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class AjaxTranslator {

	private static final Pattern ajaxRequest = Pattern.compile("(new\\s*ajax.request.*?}\\s*\\);)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
	private static final Pattern ajaxUpdater = Pattern.compile("(new\\s*ajax.update.*?}\\s*\\);)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);

	private static final Pattern ajaxRequestUrlAndBody = Pattern.compile("new\\s*ajax\\.request\\s*\\(\\s*([^,]*),\\s*\\{\\s*(.*?)\\}\\s*\\);", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
	private static final Pattern ajaxUpdaterIdUrlAndBody = Pattern.compile("new\\s*ajax\\.updater\\s*\\(\\s*['\"]([^,]*),\\s*([^,]*),\\s*\\{\\s*(.*?)\\}\\s*\\);", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);

	private static final Pattern ajaxMethod = Pattern.compile("method\\s*:\\s*([^,]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
	private static final Pattern ajaxParameters = Pattern.compile("parameters\\s*:\\s*([^}]*})\\s*,", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
	private static final Pattern ajaxRequestSuccess = Pattern.compile("onsuccess\\s*:\\s*function\\([^)]*\\)\\s*(.*?})\\s*(?:[,}]|$)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
	
	private static final Pattern ajaxUpdateSuccess = Pattern.compile("onsuccess\\s*:\\s*(.*?})\\s*(?:[,}]|$)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);

	private static final Pattern hashPattern = Pattern.compile("\\s+([^\\s=]*)\\s*=\\s*object\\.extend\\(\\s*json\\s*,\\s*Hash\\.prototype\\);", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
	
	private static final Pattern ajaxFailure = Pattern.compile("onfailure\\s*:\\s*function[^{]*(.*?})\\s*(?:[,}]|$)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
	
	private static final Pattern emptyField = Pattern.compile("^\\s*\\{\\s*\\}\\s*$", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);


	public static String convertAjaxToJquery(String input){
		String firstReplacement = convertAjaxRequestToJquery(input);
		return convertAjaxUpdaterToJquery(firstReplacement);
	}

	private static String convertAjaxUpdaterToJquery(String input) {
		Matcher request = ajaxUpdater.matcher(input);
		String id = "";
		String url = "";
		String method = "";
		String params = "";
		String onSuccess = "";
		String onFailure = "";
		String output = "";
		while (request.find()){
			Matcher urlIdAndBody = ajaxUpdaterIdUrlAndBody.matcher(request.group(1));
			if (urlIdAndBody.find()){
				id = urlIdAndBody.group(1);
				url = urlIdAndBody.group(2);
				String body = urlIdAndBody.group(3);
				Matcher methodFinder = ajaxMethod.matcher(body);
				if (methodFinder.find()){
					method = methodFinder.group(1);
				}
				Matcher parameters = ajaxParameters.matcher(body);
				if (parameters.find()){
					Matcher emptyParams = emptyField.matcher(parameters.group(1));
					if (!emptyParams.find()){
						params = parameters.group(1);
					}
				}
				Matcher success = ajaxUpdateSuccess.matcher(body);
				if (success.find()){
					onSuccess= success.group(1);
				}
				Matcher failure = ajaxFailure.matcher(body);
				if (failure.find()){
					onFailure = failure.group(1);
				}
			}
			
			StringBuffer buffer = new StringBuffer();
			buffer.append("jQuery('#" + id + ").load('" + url + "'");
			if (!params.isEmpty()){
				buffer.append(","+params);
			}
			buffer.append(","+onSuccess+" );");
			if (output.isEmpty()){
				output = input.replace(request.group(0), buffer.toString());
			} else {
				output = output.replace(request.group(0), buffer.toString());
			}
		}
		return output;
	}

	private static String convertAjaxRequestToJquery(String input){
		Matcher request = ajaxRequest.matcher(input);
		String url = "";
		String method = "";
		String params = "";
		String onSuccess = "";
		String onFailure = "";
		String output = "";
		while (request.find()){
			Matcher urlAndBody = ajaxRequestUrlAndBody.matcher(request.group(1));
			if (urlAndBody.find()){
				url = urlAndBody.group(1);
				String body = urlAndBody.group(2);
				Matcher methodFinder = ajaxMethod.matcher(body);
				if (methodFinder.find()){
					method = methodFinder.group(1);
				}
				Matcher parameters = ajaxParameters.matcher(body);
				if (parameters.find()){
					params = parameters.group(1);
				}
				Matcher success = ajaxRequestSuccess.matcher(body);
				if (success.find()){
					onSuccess = parseSuccessFunction(success.group(1));
				}
				Matcher failure = ajaxFailure.matcher(body);
				if (failure.find()){
					onFailure = failure.group(1);
				}
			}
			StringBuffer buffer = new StringBuffer();
			buffer.append("jQuery.ajax({\n");
			buffer.append("\ttype: " + method + ",\n");
			buffer.append("\t\turl: " + url + ",\n");
			buffer.append("\t\tdata: " + params + ",\n");
			buffer.append("\t\tsuccess: function(data, textStatus, xhr) " + onSuccess + ",\n");
			buffer.append("\t\terror: function(jqXHR, textStatus, errorThrown) " + onFailure + "\n");
			buffer.append("});");
			if (output.isEmpty()){
				output = input.replace(request.group(0), buffer.toString());
			} else {
				output = output.replace(request.group(0), buffer.toString());
			}
		}
		return output;
	}

	private static String parseSuccessFunction(String group) {
		Matcher ajaxJson = hashPattern.matcher(group);
		String successString = group;
		if (ajaxJson.find()){
			String varName = ajaxJson.group(1);
			String firstLayer = group.replaceAll("(?si)\\s+([^\\s=]*)\\s*=\\s*object\\.extend\\(\\s*json\\s*,\\s*Hash\\.prototype\\);", 
					"\n\tvar response = xhr.getResponseHeader('X-JSON');\n" +
					"\tvar " + varName + " = jQuery.parseJSON(response);\n");
			successString = firstLayer.replaceAll("(?si)" +varName+ "\\['([^']*)'\\];", varName + ".$1;");
		}
		return successString;
	}

}
